﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Core.Module.Interfaces.Common;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using umbraco.BusinessLogic.Utils;
using umbraco.BusinessLogic;
using Core.Module.Common;

    public static class ObjectManager
    {
        static ObjectManager()
        {
            EnsureContainer();
        }
        public static IUnityContainer Container
        {
            get
            {
                if (container == null) EnsureContainer();
                return container;
            }
        }

        #region Type Resolving
        public static TType Resolve<TType>(string name)
        {
            IUnityContainer container = Container;
            if (!string.IsNullOrEmpty(name)) return container.Resolve<TType>(name);
            else return container.Resolve<TType>();
        }
        public static TType Resolve<TType>()
        {
            IUnityContainer container = Container;
            return container.Resolve<TType>();
        }
        public static IEnumerable<TType> ResolveAll<TType>()
        {
            IUnityContainer container = Container;
            return container.ResolveAll<TType>();
        }
        #endregion

        #region Extentions

        #endregion


        #region internal
        #region initialization
        private static IUnityContainer container { get; set; }
        private static void EnsureContainer()
        {
            if (container != null) return;
            lock (container = new UnityContainer())
            {                
                container
                    .Initialization()
                    .OverrideFromConfigFile();
            }
        }

        private static IUnityContainer Initialization(this IUnityContainer container)
        {

            DateTime startAt = DateTime.Now;
            //register common classes
            container.RegisterType<ICacheManager, CacheManager>(new ContainerControlledLifetimeManager());

            foreach (Type mType in TypeFinder.FindClassesOfType<ITypeRegistrator>())
            {
                try
                {
                    ITypeRegistrator trItem = (ITypeRegistrator)Activator.CreateInstance(mType);
                    trItem.RegisterTypes(container);
                }
                catch (Exception ex)
                {///todo: have to be more generic error
                    Log.Add(LogTypes.Error, -1, "Can't Automatically RegisterTypes:" + ex.Message + "\r\n" + ex.Source + "\r\n" + ex.StackTrace);
                }
            }
            Log.Add(LogTypes.Debug, -1, "ObjectsInitializations: " + DateTime.Now.Subtract(startAt).TotalMilliseconds + "ms");
            return container;
        }

        private static IUnityContainer OverrideFromConfigFile(this IUnityContainer container)
        {
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            if (section != null)
            {
                section.Containers.Default.Configure(container);
            }
            return container;
        }
        #endregion
        #endregion

    }



   


